package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.announcement.request.AnnouncementQueryRequest;
import com.blog.cmrpersonalblog.dto.announcement.request.UserAnnouncementMessageQueryRequest;
import com.blog.cmrpersonalblog.dto.announcement.response.AnnouncementResponse;
import com.blog.cmrpersonalblog.dto.announcement.response.UserAnnouncementMessageResponse;
import com.blog.cmrpersonalblog.service.AnnouncementService;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户端公告控制器
 * 提供用户查看公告的功能，包括公告列表、详情、置顶公告、弹窗公告等
 */
@Slf4j
@RestController
@RequestMapping("/api/announcements")
@CrossOrigin(origins = "*", maxAge = 3600)
@Validated
public class UserAnnouncementController {

   @Resource
    private AnnouncementService announcementService;

    /**
     * 获取有效公告列表（用户）
     */
    @GetMapping("/list")
    public Result<IPage<AnnouncementResponse>> getValidAnnouncementList(AnnouncementQueryRequest queryRequest) {
        try {
            Long userId = null;
            if (StpUtil.isLogin()) {
                userId = StpUtil.getLoginIdAsLong();
            }
            
            // 只查询有效公告
            queryRequest.setOnlyValid(true);
            
            IPage<AnnouncementResponse> pageResult = announcementService.getValidAnnouncementList(queryRequest, userId);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("获取有效公告列表失败", e);
            return Result.error("获取公告列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取公告详情
     */
    @GetMapping("/{announcementId}")
    public Result<AnnouncementResponse> getAnnouncementDetail(@PathVariable @NotNull Long announcementId) {
        try {
            Long userId = null;
            if (StpUtil.isLogin()) {
                userId = StpUtil.getLoginIdAsLong();
            }
            
            AnnouncementResponse response = announcementService.getAnnouncementDetail(announcementId, userId);
            return Result.success(response);
        } catch (Exception e) {
            log.error("获取公告详情失败", e);
            return Result.error("获取公告详情失败：" + e.getMessage());
        }
    }

    /**
     * 获取置顶公告列表
     */
    @GetMapping("/top")
    public Result<List<AnnouncementResponse>> getTopAnnouncements() {
        try {
            Long userId = null;
            String targetAudience = "all";
            
            if (StpUtil.isLogin()) {
                userId = StpUtil.getLoginIdAsLong();
                // 根据用户角色确定目标受众
                if (StpUtil.hasRole("admin")) {
                    targetAudience = "admin";
                } else {
                    targetAudience = "user";
                }
            }
            
            List<AnnouncementResponse> announcements = announcementService.getTopAnnouncements(targetAudience, userId);
            return Result.success(announcements);
        } catch (Exception e) {
            log.error("获取置顶公告失败", e);
            return Result.error("获取置顶公告失败：" + e.getMessage());
        }
    }

    /**
     * 获取弹窗公告列表
     */
    @GetMapping("/popup")
    @SaCheckLogin
    public Result<List<AnnouncementResponse>> getPopupAnnouncements() {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            String targetAudience = StpUtil.hasRole("admin") ? "admin" : "user";
            
            List<AnnouncementResponse> announcements = announcementService.getPopupAnnouncements(targetAudience, userId);
            return Result.success(announcements);
        } catch (Exception e) {
            log.error("获取弹窗公告失败", e);
            return Result.error("获取弹窗公告失败：" + e.getMessage());
        }
    }

    /**
     * 标记公告为已读
     */
    @PostMapping("/{announcementId}/read")
    @SaCheckLogin
    public Result<Void> markAnnouncementAsRead(@PathVariable @NotNull Long announcementId) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            boolean success = announcementService.markAnnouncementAsRead(announcementId, userId);
            
            if (success) {
                return Result.success("标记已读成功");
            } else {
                return Result.error("标记已读失败");
            }
        } catch (Exception e) {
            log.error("标记公告已读失败", e);
            return Result.error("标记已读失败：" + e.getMessage());
        }
    }

    /**
     * 标记所有公告为已读
     */
    @PostMapping("/read-all")
    @SaCheckLogin
    public Result<Void> markAllAnnouncementsAsRead() {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            String targetAudience = StpUtil.hasRole("admin") ? "admin" : "user";
            
            boolean success = announcementService.markAllAnnouncementsAsRead(userId, targetAudience);
            
            if (success) {
                return Result.success("标记所有公告已读成功");
            } else {
                return Result.error("标记所有公告已读失败");
            }
        } catch (Exception e) {
            log.error("标记所有公告已读失败", e);
            return Result.error("标记所有公告已读失败：" + e.getMessage());
        }
    }

    /**
     * 获取未读公告数量
     */
    @GetMapping("/unread-count")
    @SaCheckLogin
    public Result<Integer> getUnreadAnnouncementCount() {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            String targetAudience = StpUtil.hasRole("admin") ? "admin" : "user";

            int count = announcementService.getUnreadAnnouncementCount(userId, targetAudience);
            return Result.success(count);
        } catch (Exception e) {
            log.error("获取未读公告数量失败", e);
            return Result.success(0);
        }
    }

    /**
     * 忽略公告
     */
    @PostMapping("/{announcementId}/ignore")
    @SaCheckLogin
    public Result<Void> ignoreAnnouncement(@PathVariable @NotNull Long announcementId) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            boolean success = announcementService.ignoreAnnouncement(announcementId, userId);

            if (success) {
                return Result.success("忽略公告成功");
            } else {
                return Result.error("忽略公告失败");
            }
        } catch (Exception e) {
            log.error("忽略公告失败", e);
            return Result.error("忽略公告失败：" + e.getMessage());
        }
    }

    /**
     * 取消忽略公告
     */
    @DeleteMapping("/{announcementId}/ignore")
    @SaCheckLogin
    public Result<Void> cancelIgnoreAnnouncement(@PathVariable @NotNull Long announcementId) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            boolean success = announcementService.cancelIgnoreAnnouncement(announcementId, userId);

            if (success) {
                return Result.success("取消忽略成功");
            } else {
                return Result.error("取消忽略失败");
            }
        } catch (Exception e) {
            log.error("取消忽略公告失败", e);
            return Result.error("取消忽略失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户消息中心公告列表
     */
    @GetMapping("/messages")
    @SaCheckLogin
    public Result<IPage<UserAnnouncementMessageResponse>> getUserMessageAnnouncements(
            @Validated UserAnnouncementMessageQueryRequest queryRequest) {
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            String targetAudience = StpUtil.hasRole("admin") ? "admin" : "user";

            IPage<UserAnnouncementMessageResponse> pageResult =
                announcementService.getUserMessageAnnouncementList(queryRequest, userId, targetAudience);

            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("获取用户消息中心公告列表失败", e);
            return Result.error("获取消息列表失败：" + e.getMessage());
        }
    }
}
